<template>
  <div class="seat-map-container">
    <div class="seat-legend">
      <div class="legend-item">
        <div class="seat-icon available"></div>
        <span>可选</span>
      </div>
      <div class="legend-item">
        <div class="seat-icon unavailable"></div>
        <span>不可选</span>
      </div>
      <div class="legend-item">
        <div class="seat-icon selected"></div>
        <span>已选中</span>
      </div>
    </div>
      <div class="screen">
        <div class="screen-text">
          屏幕方向
        </div>
      </div>
      <div ref="pixiContainer" class="pixi-container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue';
import { Application, Graphics, Text } from 'pixi.js';
import { EventManager } from '@/utils/EventManager';

const props = defineProps({
  seatData: {
    type: Array,
    required: true
  },
  selectedSeats: {
    type: Array,
    required: true
  }
});

const emit = defineEmits(['update:selectedSeats', 'seat-click']);

// PIXI相关变量
const pixiContainer = ref(null);
let app = null;
let seatContainer = null;
let eventManager = null;
let screenText = null;
let isDragging = false; // 拖动标志位

//不可选的颜色
const unavailableColor = 0xE74C3C;
//可选的颜色
const availableColor = 0x1DDCC2;
//选中的颜色
const selectedColor = 0x2ECC71;


/***
 * 移动端座位尺寸较小
 */
const cellSize = 20; 

// 缩略图相关
let miniMapContainer = null;
let viewportRect = null;
const miniMapScale = 0.2;
const miniMapPadding = 10;
let miniMapWidth = 0;
let miniMapHeight = 0;
const showMiniMap = ref(false);

// 初始化PIXI应用
onMounted(async () => {
  await initPixiApp();
});

// 监听座位数据变化
watch(() => props.seatData, () => {
  drawSeats();
  drawMiniMap();
}, { deep: true });

// 监听选中座位变化
watch(() => props.selectedSeats, () => {
  drawSeats();
  drawMiniMap();
}, { deep: true });


function calculateSeatBoundaries(seats) {
  if (!seats || seats.length === 0) return null;
  
  let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
  seats.forEach(seat => {
    minX = Math.min(minX, seat.x);
    maxX = Math.max(maxX, seat.x);
    minY = Math.min(minY, seat.y);
    maxY = Math.max(maxY, seat.y);
  });
  
  return { minX, maxX, minY, maxY };
}

// 初始化PIXI应用
async function initPixiApp() {  
  app = new Application();
  await app.init({ 
    background: '#f5f5f5', 
    resizeTo: pixiContainer.value,
    antialias: true
  });
  pixiContainer.value.appendChild(app.canvas);

  // 设置舞台
  // app.stage.position.set(app.screen.width / 2, app.screen.height / 2);
  app.stage.position.set(app.screen.width / 2, app.screen.height / 2);
  app.stage.sortableChildren = true;

  miniMapWidth = app.screen.width * miniMapScale;

  miniMapHeight = app.screen.height * miniMapScale;

  
  // 创建座位容器
  seatContainer = new Graphics();
  seatContainer.zIndex = 1;
  app.stage.addChild(seatContainer);
  
  // 创建缩略图容器
  miniMapContainer = new Graphics();
  miniMapContainer.zIndex = 2;
  miniMapContainer.scale.set(1); // 固定缩放比例为1

  // 创建遮罩
  const mask = new Graphics()
    .beginFill(0xFFFFFF)
    .drawRect(0, 0, miniMapWidth, miniMapHeight)
    .endFill();
  miniMapContainer.mask = mask;
  miniMapContainer.addChild(mask);

  app.stage.addChild(miniMapContainer);
  
  // 创建视口矩形
  viewportRect = new Graphics();
  viewportRect.zIndex = 3;
  viewportRect.scale.set(1); // 固定缩放比例为1
  app.stage.addChild(viewportRect);
  
  // 添加自动隐藏缩略图的定时器
  let hideTimer = null;
  const startHideTimer = () => {
    if (hideTimer) clearTimeout(hideTimer);
    hideTimer = setTimeout(() => {
      showMiniMap.value = false;
      drawMiniMap();
    }, 500);
  };
  
  // 创建事件管理器
  eventManager = new EventManager(pixiContainer.value, app, {
    maxScale: 2,
    minScale: 1
  });
  eventManager.on('drag', () => {
    isDragging = true;
    showMiniMap.value = true;
    updateViewportRect();
    drawMiniMap();

    drawRowNumbers();
    startHideTimer();
  });
  eventManager.on('dragEnd', () => {
    // 计算边界吸附
    const seats = props.seatData;
    if (!seats || seats.length === 0) return;
    
    let {minX,maxX,minY,maxY } = calculateSeatBoundaries(seats);
  
    
    const centerX = (minX  * cellSize + maxX  * cellSize) / 2;
    const centerY = (minY  * cellSize + maxY  * cellSize) / 2;
    
    // 计算当前视口位置和缩放比例
    const stagePos = app.stage.position;
    const scalex = 1 / app.stage.scale.x;
    const scaley = 1 / app.stage.scale.y;
    console.log('scalex',scalex,'scaley',scaley);
    const visibleWidth = app.screen.width ;
    const visibleHeight = app.screen.height ;
    // 计算边界吸附（考虑缩放比例）
    const maxOffsetX =  visibleWidth  > (maxX * cellSize  + centerX)   ? visibleWidth - (centerX* app.stage.scale.x)  -(cellSize * app.stage.scale.x) : (maxX * cellSize + centerX) ;
    const minOffsetX = (minX * cellSize + centerX* app.stage.scale.x) ;
    const maxOffsetY = visibleHeight > (maxY * cellSize + centerY) * scaley ? visibleHeight -  (centerY* app.stage.scale.y)   : (maxY * cellSize + centerY) * scaley ;
    const minOffsetY = (minY * cellSize + centerY) ;
    console.log('app.stage',app.stage.position);

    // 应用边界吸附
    stagePos.x = Math.min(maxOffsetX, Math.max(minOffsetX, stagePos.x));
    stagePos.y = Math.min(maxOffsetY, Math.max(minOffsetY, stagePos.y));
   
    console.log('maxOffsetX',maxOffsetX,'minOffsetX',minOffsetX,'maxOffsetY',maxOffsetY,'minOffsetY',minOffsetY);
    console.log('stagePos',stagePos);
    drawRowNumbers();
    drawMiniMap();
  });

  eventManager.on('zoom', (value) => {
    console.log('zoom',(1/value.scale));
    miniMapContainer.scale.set(1/app.stage.scale.x);
    showMiniMap.value = false;
    updateViewportRect();
    drawRowNumbers();
    drawMiniMap();
  });

  // 绘制座位
  drawSeats();
  drawRowNumbers();
  drawMiniMap();
}

// 绘制座位
function drawSeats() {
  seatContainer.clear();
  
  const seats = props.seatData;
  if (!seats || seats.length === 0) return;
  

  let {minX,maxX,minY,maxY } = calculateSeatBoundaries(seats);
  
  // 计算中心偏移
  const centerX = (minX + maxX) / 2;
  const centerY = (minY + maxY) / 2;
  
  // 绘制每个座位
  seats.forEach(seat => {
    const x = (seat.x - centerX) * cellSize;
    const y = (seat.y - centerY) * cellSize;
    let fillColor;
    let alpha = 1;
    // seat.position = {x,y};
    
    if (seat.status === 'unavailable') {
      fillColor = unavailableColor; // 红色 - 不可选
    } else {
      const isSelected = props.selectedSeats.some(s => s.x === seat.x && s.y === seat.y);
      fillColor = isSelected ? selectedColor : availableColor; // 绿色 - 已选中，蓝色 - 可选
    }

    const seatGraphics = new Graphics()
      .beginFill(fillColor, alpha)
      .drawRoundedRect(x, y, cellSize * 0.8, cellSize * 0.8, 4)
      .endFill();
    
    if (seat.status !== 'unavailable') {
      seatGraphics.eventMode = 'static';
      seatGraphics.cursor = 'pointer';
      seatGraphics.on('pointerup', () => {
        if (!isDragging) {
          console.log('click',props.selectedSeats);
          toggleSeatSelection(seat);
        }
        isDragging = false;
      });
    }
    seatContainer.addChild(seatGraphics);
  });
}

// 绘制行号
function drawRowNumbers() {
  const seats = props.seatData;
  if (!seats || seats.length === 0) return;
  
  const uniqueRows = [...new Set(seats.map(seat => seat.y))].sort((a, b) => a - b);
  
  let {minX,maxX,minY,maxY } = calculateSeatBoundaries(seats);

  const centerY = (minY + maxY) / 2;
  const centerX = (minX + maxX) / 2;
  
  const existingRowNumbers = app.stage.children.filter(child => child instanceof Text && child !== screenText);
  existingRowNumbers.forEach(text => app.stage.removeChild(text));
  
  // 计算所有行号的位置范围
  const localPoint = app.stage.toLocal({ x: miniMapPadding, y: miniMapPadding });
  const baseX = localPoint.x + 5;
  const firstY = (uniqueRows[0] - centerY) * cellSize + 10;
  const lastY = (uniqueRows[uniqueRows.length - 1] - centerY) * cellSize + 10;
  

  // 先移除所有zIndex为9的Graphics对象
  app.stage.children.filter(child => child.zIndex === 9).forEach(child => app.stage.removeChild(child));

  // 创建统一的背景矩形
  const bg = new Graphics()
    .beginFill(0x000000, 0.4)
    .drawRoundedRect(0, 0, 30, lastY - firstY + 20, 4)
    .endFill();
  bg.position.set(baseX - 25, firstY - 10);
  bg.zIndex = 9;
  app.stage.addChild(bg);
  
  // 创建所有行号文本
  uniqueRows.forEach(row => {
    const y = (row - centerY) * cellSize + 10;
    
    const rowText = new Text(`${row}`, {
      fontFamily: 'Arial',
      fontSize: Math.min(14, 12 / (1 / Math.min(app.stage.scale.x, app.stage.scale.y))),
      fill: 0xFFFFFF, // 白色文本
      align: 'right'
    });
    
    rowText.anchor.set(1, 0.5);
    rowText.position.set(baseX, y);
    rowText.zIndex = 10;
    
    app.stage.addChild(rowText);
  });
}

// 绘制缩略图
function drawMiniMap() {
  if (!miniMapContainer || !app) return;
  
  miniMapContainer.clear();
  miniMapContainer.visible = showMiniMap.value;
  viewportRect.visible = showMiniMap.value;
  
  if (!showMiniMap.value) return;
  
  miniMapContainer.beginFill(0x000000, 0.5)
    .drawRect(0, 0, miniMapWidth, miniMapHeight)
    .endFill();
  
  const miniSeatSize = cellSize * miniMapScale;
  
  // 找出座位的最大和最小坐标，用于居中显示（与drawSeats保持一致）
  const seats = props.seatData;
  if (!seats || seats.length === 0) return;
  

  let {minX,maxX,minY,maxY } = calculateSeatBoundaries(seats);

  
  // 计算中心偏移
  const centerX = (minX + maxX) / 2;
  const centerY = (minY + maxY) / 2;
  
  const visibleWidth = app.screen.width ;
  const visibleHeight = app.screen.height;

  props.seatData.forEach(seat => {
    // 使用与calculateViewportRect相同的坐标转换逻辑
    // 计算舞台在x轴上的位置
    const stageX = -app.stage.position.x  + visibleWidth / 2 ;
    // 计算舞台在y轴上的位置
    const stageY = -app.stage.position.y  + visibleHeight / 2;

    
    // 计算座位在x轴上的位置，考虑缩放比例
    const x =  ((seat.x - centerX) * miniSeatSize * app.stage.scale.x) - stageX * miniMapScale + miniMapWidth  / 2;
    const y = ((seat.y - centerY) * miniSeatSize * app.stage.scale.y) - stageY * miniMapScale + miniMapHeight / 2;
    
    let fillColor;
    if (seat.status === 'unavailable') {
      fillColor = unavailableColor;
    } else {
      const isSelected = props.selectedSeats.some(s => s.x === seat.x && s.y === seat.y);
      fillColor = isSelected ? selectedColor : availableColor;
    }
    //绘制座位大小，根据app.stage.scale调整
    let seatWidth = miniSeatSize *  0.8 *  app.stage.scale.x;
    let seatHeight = miniSeatSize * 0.8 * app.stage.scale.x;
    miniMapContainer.beginFill(fillColor)
      .drawRect(x, y, seatWidth, seatHeight)
      .endFill();
  });
  
  updateViewportRect();
}

// 计算视口矩形位置
function calculateViewportRect(app, miniMapScale) {
  const visibleWidth = app.screen.width / app.stage.scale.x;
  const visibleHeight = app.screen.height / app.stage.scale.y;
  const stageX = -app.stage.position.x / app.stage.scale.x + visibleWidth / 2;
  const stageY = -app.stage.position.y / app.stage.scale.y + visibleHeight / 2;
  
  const rectX = (stageX * miniMapScale);
  const rectY = (stageY * miniMapScale);
  
  return { rectX, rectY,visibleWidth,visibleHeight };
}

// 更新视口矩形
function updateViewportRect() {
  if (!viewportRect || !app) return;
  
  viewportRect.clear();
  
  // 计算视口矩形的位置
  const localPoint = app.stage.toLocal({ x: miniMapPadding, y: app.screen.height - miniMapHeight - miniMapPadding  });
  miniMapContainer.position.set(localPoint.x, localPoint.y);

  const { rectX, rectY,visibleWidth,visibleHeight } = calculateViewportRect(app, miniMapScale);
  const rectWidth = visibleWidth * miniMapScale;
  const rectHeight = visibleHeight * miniMapScale;
  viewportRect.lineStyle(1, 0xFF0000)
    .drawRect(rectX, rectY, rectWidth, rectHeight);
  viewportRect.position.set(localPoint.x, localPoint.y);
  viewportRect.visible = showMiniMap.value;
}

// 切换座位选择状态
function toggleSeatSelection(seat) {
  const index = props.selectedSeats.findIndex(s => s.x === seat.x && s.y === seat.y);
  console.log('toggleSeatSelection', index);
  if (index === -1) {
    emit('update:selectedSeats', [...props.selectedSeats, {
      ...seat,
      row: seat.y,
      column: seat.x
    }]);
  } else {
    const newSelectedSeats = [...props.selectedSeats];
    newSelectedSeats.splice(index, 1);
    emit('update:selectedSeats', newSelectedSeats);
  }
  
  emit('seat-click', seat);
}
</script>

<style scoped>
.seat-map-container {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: #fff;
}

.pixi-container {
  width: 100%;
  flex: 1;
  touch-action: none;
}

.screen{
  width: 310px;
  border-top: 21px solid #DFDFDF;
  border-right: 30px solid transparent;
  border-left: 30px solid transparent;
  color: white;
  position: absolute;
  top: 46px;
  z-index: 2;
  left: 50%;
  transform: translateX(-50%);
}

.screen-text {
  text-align: center;
  white-space: nowrap;
  font-size: 17px;
  font-weight: 600;
  margin-top: -19px;
}

.seat-legend {
  display: flex;
  justify-content: center;
  margin: 15px 0; 
}

.legend-item {
  display: flex;
  align-items: center;
  margin: 0 10px;
}

.seat-icon {
  width: 16px;
  height: 16px;
  border-radius: 3px;
  margin-right: 5px;
}

.seat-icon.available {
  background-color: #1DDCC2;
}

.seat-icon.unavailable {
  background-color: #E74C3C;
}

.seat-icon.selected {
  background-color: #2ECC71;
}
</style>